﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Issues.HeadmanVillageNeedsDraughtAnimalsIssueBehavior
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System;
using System.Collections.Generic;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.Conversation;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Issues
{
  public class HeadmanVillageNeedsDraughtAnimalsIssueBehavior : CampaignBehaviorBase
  {
    private const IssueBase.IssueFrequency HeadmanVillageNeedsDraughtAnimalsIssueFrequency = IssueBase.IssueFrequency.VeryCommon;

    public override void RegisterEvents()
    {
      CampaignEvents.OnCheckForIssueEvent.AddNonSerializedListener((object) this, new Action<Hero>(this.OnCheckForIssue));
    }

    public override void SyncData(IDataStore dataStore)
    {
    }

    private bool ConditionsHold(Hero issueGiver)
    {
      if (issueGiver.CurrentSettlement == null || !issueGiver.IsHeadman)
        return false;
      Village village = issueGiver.CurrentSettlement.Village;
      if (village.GetProsperityLevel() != SettlementComponent.ProsperityLevel.Low && village.GetProsperityLevel() != SettlementComponent.ProsperityLevel.Mid)
        return false;
      return village.VillageType == DefaultVillageTypes.IronMine || village.VillageType == DefaultVillageTypes.ClayMine || village.VillageType == DefaultVillageTypes.SaltMine || village.VillageType == DefaultVillageTypes.SilverMine || village.VillageType == DefaultVillageTypes.Lumberjack;
    }

    public void OnCheckForIssue(Hero hero)
    {
      if (this.ConditionsHold(hero))
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(new PotentialIssueData.StartIssueDelegate(this.OnSelected), typeof (HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue), IssueBase.IssueFrequency.VeryCommon));
      else
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(typeof (HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue), IssueBase.IssueFrequency.VeryCommon));
    }

    private IssueBase OnSelected(in PotentialIssueData pid, Hero issueOwner)
    {
      return (IssueBase) new HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue(issueOwner);
    }

    public class HeadmanVillageNeedsDraughtAnimalsIssue : IssueBase
    {
      private const int IssueActiveTime = 30;
      private const int QuestDuration = 30;
      private const int VillageHearthConstant = 300;
      private const int AlternativeSolutionTroopTierRequirement = 2;
      private const int CompanionRequiredSkillLevel = 120;
      [CachedData]
      private readonly MBList<ItemObject> _possibleAnimals;
      [SaveableField(1)]
      private ItemObject _selectedAnimal;
      [SaveableField(2)]
      private bool _isQuestWithMeatOffer;
      [SaveableField(3)]
      private int _requestedAnimalAmount;

      internal static void AutoGeneratedStaticCollectObjectsHeadmanVillageNeedsDraughtAnimalsIssue(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._selectedAnimal);
      }

      internal static object AutoGeneratedGetMemberValue_selectedAnimal(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue) o)._selectedAnimal;
      }

      internal static object AutoGeneratedGetMemberValue_isQuestWithMeatOffer(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue) o)._isQuestWithMeatOffer;
      }

      internal static object AutoGeneratedGetMemberValue_requestedAnimalAmount(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue) o)._requestedAnimalAmount;
      }

      public override IssueBase.AlternativeSolutionScaleFlag AlternativeSolutionScaleFlags
      {
        get => IssueBase.AlternativeSolutionScaleFlag.Duration;
      }

      private ItemObject _meatItem => Game.Current.ObjectManager.GetObject<ItemObject>("meat");

      private int OfferedMeatAmount
      {
        get
        {
          return (300 + this._selectedAnimal.Value * this._requestedAnimalAmount) / this._meatItem.Value * 2;
        }
      }

      private int GoldRequiredForAlternativeSolution
      {
        get
        {
          return (int) ((double) (this._selectedAnimal.Value * this._requestedAnimalAmount) * 0.699999988079071);
        }
      }

      public override int AlternativeSolutionBaseNeededMenCount
      {
        get => 3 + MathF.Ceiling(3f * this.IssueDifficultyMultiplier);
      }

      protected override int AlternativeSolutionBaseDurationInDaysInternal
      {
        get => 3 + MathF.Ceiling(5f * this.IssueDifficultyMultiplier);
      }

      protected override int RewardGold
      {
        get
        {
          return this._isQuestWithMeatOffer ? 0 : 500 + this._selectedAnimal.Value * this._requestedAnimalAmount;
        }
      }

      public override TextObject IssueBriefByIssueGiver
      {
        get
        {
          return new TextObject("{=9nxTUZkO}We do have a problem. Last winter was hard on our animals. A number died from disease, and others were taken by wolves. We'd go to town to buy more, but, well, herds make a tempting target for bandits and we're not really suited to fight them. We can't afford to slaughter even the oldest and weakest of our animals because we need them to pull the plough. Maybe you can help us?[if:convo_grave][ib:demure2]");
        }
      }

      public override TextObject IssueAcceptByPlayer
      {
        get => new TextObject("{=nvaLVB5f}Tell me your needs.");
      }

      public override TextObject IssueQuestSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject empty = TextObject.Empty;
          TextObject explanationByIssueGiver;
          if (this._isQuestWithMeatOffer)
          {
            explanationByIssueGiver = new TextObject("{=aExKdXmx}We need {REQUESTED_ANIMAL_AMOUNT} {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%}.[if:convo_normal][ib:demure] To be honest our village is poor and our coffers are empty. We can make payment only as meat - the meat of the old animals that we'll slaughter as soon as you bring us the new ones. We can offer {MEAT_AMOUNT} loads of meat, will you accept that, {?PLAYER.GENDER}madam{?}sir{\\?}?");
            explanationByIssueGiver.SetTextVariable("MEAT_AMOUNT", this.OfferedMeatAmount);
          }
          else
          {
            explanationByIssueGiver = new TextObject("{=TEhwK74M}We are willing to pay {REWARD}{GOLD_ICON} denars for {REQUESTED_ANIMAL_AMOUNT} healthy and strong [if:convo_normal][ib:demure]{.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%}. Unlike us, I'm sure you can travel distant villages easily and find the finest and cheapest ones there.");
            explanationByIssueGiver.SetTextVariable("REWARD", this.RewardGold);
          }
          explanationByIssueGiver.SetTextVariable("REQUESTED_ANIMAL_AMOUNT", this._requestedAnimalAmount);
          explanationByIssueGiver.SetTextVariable("SELECTED_ANIMAL", this._selectedAnimal.Name);
          explanationByIssueGiver.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssuePlayerResponseAfterAlternativeExplanation
      {
        get
        {
          return new TextObject("{=qYSrlr4q}Maybe I should send one of my men to find the animals you need.");
        }
      }

      public override TextObject IssueAlternativeSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject explanationByIssueGiver = new TextObject("{=bvEOmHWd}I think a man who knows how to trade alongside {ALTERNATIVE_TROOP_AMOUNT} [if:convo_undecided_open]fighters can get the job done without trouble. they will need {GOLD_REQUIRED_FOR_ALTERNATIVE_SOLUTION}{GOLD_ICON} denars to buy the animals. You or one of your companions, {?PLAYER.GENDER}madam{?}sir{\\?} - it doesn't matter for us as long as you find the animals we need...");
          explanationByIssueGiver.SetTextVariable("ALTERNATIVE_TROOP_AMOUNT", this.GetTotalAlternativeSolutionNeededMenCount());
          explanationByIssueGiver.SetTextVariable("GOLD_REQUIRED_FOR_ALTERNATIVE_SOLUTION", this.GoldRequiredForAlternativeSolution);
          explanationByIssueGiver.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssueQuestSolutionAcceptByPlayer
      {
        get => new TextObject("{=iq3yEuO9}All right. I will bring your animals by myself.");
      }

      public override TextObject IssueAlternativeSolutionAcceptByPlayer
      {
        get
        {
          return new TextObject("{=BMQQSeTp}I'm sure my men will find what you need and bring them to you in time.");
        }
      }

      public override TextObject IssueAlternativeSolutionResponseByIssueGiver
      {
        get
        {
          return new TextObject("{=D9LxQxNa}Thank you for your help {?PLAYER.GENDER}madam{?}sir{\\?}.[if:convo_bemused][ib:demure2] We will be waiting for your men. Good luck to you all.");
        }
      }

      public override TextObject IssueDiscussAlternativeSolution
      {
        get
        {
          return new TextObject("{=jol73R8f}We are still waiting for your men to arrive, {?PLAYER.GENDER}ma'am{?}sir{\\?}. The village needs the animals they are bringing.");
        }
      }

      public override bool IsThereAlternativeSolution => true;

      public override bool IsThereLordSolution => false;

      protected override TextObject AlternativeSolutionStartLog
      {
        get
        {
          TextObject parent = new TextObject("{=F16k4H7R}{QUEST_GIVER.LINK} told you that {?QUEST_GIVER.GENDER}she{?}he{\\?} needs {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%} for {?QUEST_GIVER.GENDER}her{?}his{\\?} village. {?QUEST_GIVER.GENDER}She{?}He{\\?} will pay you {REWARD_GOLD}{GOLD_ICON} denars when the animals are delivered. You asked your {COMPANION.LINK} and {ALTERNATIVE_TROOP_AMOUNT} of your men to deliver {REQUESTED_ANIMAL_AMOUNT} {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%} to {QUEST_GIVER.LINK}. They will rejoin your party in {RETURN_DAYS} days.");
          parent.SetTextVariable("ALTERNATIVE_TROOP_AMOUNT", this.GetTotalAlternativeSolutionNeededMenCount());
          parent.SetTextVariable("REQUESTED_ANIMAL_AMOUNT", this._requestedAnimalAmount);
          parent.SetTextVariable("SELECTED_ANIMAL", this._selectedAnimal.Name);
          parent.SetTextVariable("RETURN_DAYS", this.GetTotalAlternativeSolutionDurationInDays());
          parent.SetTextVariable("REWARD_GOLD", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.IssueOwner.CharacterObject, parent);
          StringHelpers.SetCharacterProperties("COMPANION", this.AlternativeSolutionHero.CharacterObject, parent);
          return parent;
        }
      }

      public override TextObject Title
      {
        get => new TextObject("{=MXLcZPaO}Village Needs Draught Animals");
      }

      public override TextObject Description
      {
        get
        {
          return new TextObject("{=Ntv5KPFe}Headman in the village requested draught animals to replace them with old ones.");
        }
      }

      public HeadmanVillageNeedsDraughtAnimalsIssue(Hero issueOwner)
      {
        MBList<ItemObject> mbList = new MBList<ItemObject>();
        mbList.Add(Game.Current.ObjectManager.GetObject<ItemObject>("cow"));
        mbList.Add(Game.Current.ObjectManager.GetObject<ItemObject>("mule"));
        mbList.Add(Game.Current.ObjectManager.GetObject<ItemObject>("sumpter_horse"));
        this._possibleAnimals = mbList;
        // ISSUE: explicit constructor call
        base.\u002Ector(issueOwner, CampaignTime.DaysFromNow(30f));
        this._selectedAnimal = this._possibleAnimals.GetRandomElement<ItemObject>();
        this._isQuestWithMeatOffer = (double) issueOwner.CurrentSettlement.Village.Hearth <= 300.0;
        this._requestedAnimalAmount = MathF.Round((float) (int) (5000.0 / (double) this._selectedAnimal.Value) * this.IssueDifficultyMultiplier);
      }

      protected override float GetIssueEffectAmountInternal(IssueEffect issueEffect)
      {
        if (issueEffect == DefaultIssueEffects.VillageHearth)
          return -0.2f;
        return issueEffect == DefaultIssueEffects.IssueOwnerPower ? -0.1f : 0.0f;
      }

      public override bool DoTroopsSatisfyAlternativeSolution(
        TroopRoster troopRoster,
        out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(troopRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2);
      }

      public override bool IsTroopTypeNeededByAlternativeSolution(CharacterObject character)
      {
        return character.Tier >= 2;
      }

      public override (SkillObject, int) GetAlternativeSolutionSkill(Hero hero)
      {
        return (hero.GetSkillValue(DefaultSkills.Riding) >= hero.GetSkillValue(DefaultSkills.Trade) ? DefaultSkills.Riding : DefaultSkills.Trade, 120);
      }

      public override bool AlternativeSolutionCondition(out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(MobileParty.MainParty.MemberRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2) && QuestHelper.CheckGoldForAlternativeSolution(this.GoldRequiredForAlternativeSolution, ref explanation);
      }

      public override IssueBase.IssueFrequency GetFrequency()
      {
        return IssueBase.IssueFrequency.VeryCommon;
      }

      public override bool IssueStayAliveConditions()
      {
        return !this.IssueOwner.CurrentSettlement.IsRaided && !this.IssueOwner.CurrentSettlement.IsUnderRaid;
      }

      public override void AlternativeSolutionStartConsequence()
      {
        GiveGoldAction.ApplyBetweenCharacters(Hero.MainHero, (Hero) null, this.GoldRequiredForAlternativeSolution);
      }

      protected override bool CanPlayerTakeQuestConditions(
        Hero issueGiver,
        out IssueBase.PreconditionFlags flags,
        out Hero relationHero,
        out SkillObject skill)
      {
        flags = IssueBase.PreconditionFlags.None;
        relationHero = (Hero) null;
        skill = (SkillObject) null;
        if ((double) issueGiver.GetRelationWithPlayer() < -10.0)
        {
          flags |= IssueBase.PreconditionFlags.Relation;
          relationHero = issueGiver;
        }
        if (FactionManager.IsAtWarAgainstFaction(issueGiver.MapFaction, Hero.MainHero.MapFaction))
          flags |= IssueBase.PreconditionFlags.AtWar;
        return flags == IssueBase.PreconditionFlags.None;
      }

      protected override void OnGameLoad()
      {
      }

      protected override void HourlyTick()
      {
      }

      protected override QuestBase GenerateIssueQuest(string questId)
      {
        return (QuestBase) new HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest(questId, this.IssueOwner, CampaignTime.DaysFromNow(30f), this._selectedAnimal, this._requestedAnimalAmount, this._isQuestWithMeatOffer, this.OfferedMeatAmount, this.RewardGold);
      }

      protected override void CompleteIssueWithTimedOutConsequences()
      {
      }

      protected override int CompanionSkillRewardXP
      {
        get => (int) (500.0 + 700.0 * (double) this.IssueDifficultyMultiplier);
      }

      protected override void AlternativeSolutionEndWithSuccessConsequence()
      {
        this.IssueOwner.AddPower(10f);
        ChangeRelationAction.ApplyPlayerRelation(this.IssueOwner, 5);
        this.IssueOwner.CurrentSettlement.Village.Hearth += 30f;
        if (!this._isQuestWithMeatOffer)
          return;
        MobileParty.MainParty.ItemRoster.AddToCounts(Game.Current.ObjectManager.GetObject<ItemObject>("meat"), this.OfferedMeatAmount);
      }
    }

    public class HeadmanVillageNeedsDraughtAnimalsIssueQuest : QuestBase
    {
      [SaveableField(1)]
      private ItemObject _requestedAnimal;
      [SaveableField(2)]
      private int _requestedAnimalAmount;
      private int _currentAnimalAmount;
      [SaveableField(3)]
      private bool _isQuestWithMeatOffer;
      [SaveableField(4)]
      private int _discountValue;
      [SaveableField(5)]
      private int _offeredMeatAmount;
      [SaveableField(6)]
      private JournalLog _questProgressLogTest;

      internal static void AutoGeneratedStaticCollectObjectsHeadmanVillageNeedsDraughtAnimalsIssueQuest(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._requestedAnimal);
        collectedObjects.Add((object) this._questProgressLogTest);
      }

      internal static object AutoGeneratedGetMemberValue_requestedAnimal(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest) o)._requestedAnimal;
      }

      internal static object AutoGeneratedGetMemberValue_requestedAnimalAmount(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest) o)._requestedAnimalAmount;
      }

      internal static object AutoGeneratedGetMemberValue_isQuestWithMeatOffer(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest) o)._isQuestWithMeatOffer;
      }

      internal static object AutoGeneratedGetMemberValue_discountValue(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest) o)._discountValue;
      }

      internal static object AutoGeneratedGetMemberValue_offeredMeatAmount(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest) o)._offeredMeatAmount;
      }

      internal static object AutoGeneratedGetMemberValue_questProgressLogTest(object o)
      {
        return (object) ((HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest) o)._questProgressLogTest;
      }

      public override TextObject Title
      {
        get => new TextObject("{=MXLcZPaO}Village Needs Draught Animals");
      }

      public override bool IsRemainingTimeHidden => false;

      private TextObject QuestStartedLogText
      {
        get
        {
          TextObject parent = new TextObject("{=V7YG3nKb}{QUEST_GIVER.LINK} told you that {?QUEST_GIVER.GENDER}she{?}he{\\?} needs {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%} for {?QUEST_GIVER.GENDER}her{?}his{\\?} village. {?QUEST_GIVER.GENDER}She{?}He{\\?} asked you to bring {REQUESTED_ANIMAL_AMOUNT} {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%} to {?QUEST_GIVER.GENDER}her{?}him{\\?}.");
          parent.SetTextVariable("REQUESTED_ANIMAL_AMOUNT", this._requestedAnimalAmount);
          parent.SetTextVariable("SELECTED_ANIMAL", this._requestedAnimal.Name);
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject QuestStartedLogTextWithMeat
      {
        get
        {
          TextObject parent = new TextObject("{=7VUNi3zy}{QUEST_GIVER.LINK} will make payment as {MEAT_AMOUNT} meat when the task is done.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("MEAT_AMOUNT", this._offeredMeatAmount);
          return parent;
        }
      }

      private TextObject QuestSuccessLogText
      {
        get
        {
          TextObject parent = new TextObject("{=uubL3Uck}You brought {REQUESTED_ANIMAL_AMOUNT} {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}{.%} to {?QUEST_GIVER.GENDER}her{?}him{\\?} as promised.");
          parent.SetTextVariable("REQUESTED_ANIMAL_AMOUNT", this._requestedAnimalAmount);
          parent.SetTextVariable("SELECTED_ANIMAL", this._requestedAnimal.Name);
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject QuestStartedLogTextWithDenars
      {
        get
        {
          TextObject parent = new TextObject("{=7LjTNs1k}{QUEST_GIVER.LINK} will pay you {REWARD_GOLD}{GOLD_ICON} denars when the task is done.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("REWARD_GOLD", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject QuestCanceledWarDeclaredLog
      {
        get
        {
          TextObject parent = new TextObject("{=vW6kBki9}Your clan is now at war with {QUEST_GIVER.LINK}'s realm. Your agreement with {QUEST_GIVER.LINK} is canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject PlayerDeclaredWarQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=bqeWVVEE}Your actions have started a war with {QUEST_GIVER.LINK}'s faction. {?QUEST_GIVER.GENDER}She{?}He{\\?} cancels your agreement and the quest is a failure.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject QuestGiverVillageRaided
      {
        get
        {
          TextObject parent = new TextObject("{=gJG0xmAq}{QUEST_GIVER.LINK}'s village {QUEST_SETTLEMENT} was raided. Your agreement with {QUEST_GIVER.LINK} is canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("QUEST_SETTLEMENT", this.QuestGiver.CurrentSettlement.EncyclopediaLinkWithName);
          return parent;
        }
      }

      private TextObject QuestFailedWithTimeOutLogText
      {
        get
        {
          TextObject parent = new TextObject("{=xvCzjcjU}You failed to deliver {REQUESTED_ANIMAL_AMOUNT} {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{REQUESTED_ANIMAL}{.s}{?}{REQUESTED_ANIMAL}{\\?}{.%} to {QUEST_GIVER.LINK} in time.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("REQUESTED_ANIMAL_AMOUNT", this._requestedAnimalAmount);
          parent.SetTextVariable("REQUESTED_ANIMAL", this._requestedAnimal.Name);
          return parent;
        }
      }

      public HeadmanVillageNeedsDraughtAnimalsIssueQuest(
        string questId,
        Hero giverHero,
        CampaignTime duration,
        ItemObject requestedAnimal,
        int requestedAnimalAmount,
        bool isQuestWithMeatOffer,
        int offeredMeatAmount,
        int rewardGold)
        : base(questId, giverHero, duration, rewardGold)
      {
        this._isQuestWithMeatOffer = isQuestWithMeatOffer;
        this._requestedAnimal = requestedAnimal;
        this._requestedAnimalAmount = requestedAnimalAmount;
        this._offeredMeatAmount = offeredMeatAmount;
        this.CalculateRequestedAnimalCountOnPlayer();
        this.SetDialogs();
        this.InitializeQuestOnCreation();
        if (isQuestWithMeatOffer || (double) MBRandom.RandomFloat > 0.699999988079071)
          return;
        this._discountValue = (int) ((double) this.RewardGold * 0.30000001192092896);
      }

      private void QuestAcceptedConsequences()
      {
        this.StartQuest();
        this.AddTrackedObject((ITrackableCampaignObject) this.QuestGiver.CurrentSettlement);
        TextObject taskName = new TextObject("{=yc9rGlzb}Ready to deliver {.%}{?(REQUESTED_ANIMAL_AMOUNT > 1)}{PLURAL(SELECTED_ANIMAL)}{?}{SELECTED_ANIMAL}{\\?}:{.%}");
        taskName.SetTextVariable("SELECTED_ANIMAL", this._requestedAnimal.Name);
        taskName.SetTextVariable("REQUESTED_ANIMAL_AMOUNT", this._requestedAnimalAmount);
        this._questProgressLogTest = this.AddDiscreteLog(this.QuestStartedLogText, taskName, this._currentAnimalAmount, this._requestedAnimalAmount);
        this.AddLog(this._isQuestWithMeatOffer ? this.QuestStartedLogTextWithMeat : this.QuestStartedLogTextWithDenars);
      }

      protected override void SetDialogs()
      {
        this.OfferDialogFlow = DialogFlow.CreateDialogFlow("issue_classic_quest_start").NpcLine(new TextObject("{=msDCQIY7}Thank you, {?PLAYER.GENDER}madam{?}sir{\\?}. [if:convo_grateful][ib:confident]In these hard times, people like you are a gift from Heaven… The village will never forget that you were willing to help. Good luck.")).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestAcceptedConsequences)).CloseDialog();
        TextObject npcText1 = new TextObject("{=rRGbn0Sm}Thank you {?PLAYER.GENDER}madam{?}sir{\\?}. [if:convo_focused_happy][ib:normal]You did a great favor to people of {ISSUE_VILLAGE}.");
        npcText1.SetTextVariable("ISSUE_VILLAGE", this.QuestGiver.CurrentSettlement.EncyclopediaLinkWithName);
        TextObject npcDiscountLine = new TextObject("{=p9rzYV4T}Things have gotten worse for the village, [if:convo_dismayed][ib:nervous2]since we last met {?PLAYER.GENDER}madam{?}sir{\\?}. Is it possible that we could pay you a bit less, what about {DISCOUNTED_REWARD}{GOLD_ICON} denars?");
        TextObject npcText2 = new TextObject("{=4kealpZK}Have you brought the animals {?PLAYER.GENDER}madam{?}sir{\\?}?");
        this.DiscussDialogFlow = DialogFlow.CreateDialogFlow("quest_discuss").NpcLine(npcText2).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).BeginPlayerOptions().PlayerOption(new TextObject("{=CjuVoxaC}Yes, Here are your animals.")).Condition(new ConversationSentence.OnConditionDelegate(this.CheckIfPlayerHasEnoughAnimals)).BeginNpcOptions().NpcOption(npcDiscountLine, (ConversationSentence.OnConditionDelegate) (() =>
        {
          if (this._discountValue <= 0)
            return false;
          npcDiscountLine.SetTextVariable("DISCOUNTED_REWARD", this.RewardGold - this._discountValue);
          npcDiscountLine.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return true;
        })).BeginPlayerOptions().PlayerOption(new TextObject("{=KBmAqg54}No problem, you can pay what you can afford.")).NpcLine(npcText1).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestSuccessPlayerDeliveredAnimalsWithAcceptingDiscount)).CloseDialog().PlayerOption(new TextObject("{=kYc90hEl}Sorry, but the price is what we agreed on. I can't lower it.")).NpcLine(new TextObject("{=r4pLtP5V}You're right. We agreed on this price. Thank you for your efforts.[if:convo_nervous][ib:normal]")).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestSuccessPlayerDeliveredAnimalsWithoutAcceptingDiscount)).CloseDialog().EndPlayerOptions().NpcOption(new TextObject("{=l8ezl95j}Thank you {?PLAYER.GENDER}madam{?}sir{\\?}.[if:convo_calm_friendly] Here is what we promised."), (ConversationSentence.OnConditionDelegate) null).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestSuccessPlayerDeliveredAnimalsNormal)).CloseDialog().EndNpcOptions().PlayerOption(new TextObject("{=PI6ikMsc}I'm working on it.")).NpcLine(new TextObject("{=4MQQf3wp}We are waiting for your arrival. ")).CloseDialog().EndPlayerOptions();
      }

      private void CalculateRequestedAnimalCountOnPlayer()
      {
        int num = 0;
        foreach (ItemRosterElement itemRosterElement in MobileParty.MainParty.ItemRoster)
        {
          if (itemRosterElement.EquipmentElement.Item == this._requestedAnimal)
            num += itemRosterElement.Amount;
        }
        this._currentAnimalAmount = num;
      }

      private bool CheckIfPlayerHasEnoughAnimals()
      {
        this.CalculateRequestedAnimalCountOnPlayer();
        return this._currentAnimalAmount >= this._requestedAnimalAmount;
      }

      private void QuestSuccessPlayerDeliveredAnimalsNormal()
      {
        ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, 5);
        this.QuestGiver.CurrentSettlement.Village.Hearth += 30f;
        this.ApplyRewards(false);
        this.CompleteQuestWithSuccess();
      }

      private void QuestSuccessPlayerDeliveredAnimalsWithAcceptingDiscount()
      {
        ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, 8);
        TraitLevelingHelper.OnIssueSolvedThroughBetrayal(this.QuestGiver, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Mercy, 30)
        });
        this.QuestGiver.CurrentSettlement.Village.Hearth += 80f;
        this.ApplyRewards(true);
        foreach (Hero notable in (List<Hero>) this.QuestGiver.CurrentSettlement.Notables)
        {
          if (notable != this.QuestGiver)
            ChangeRelationAction.ApplyPlayerRelation(notable, 3);
        }
        this.CompleteQuestWithSuccess();
      }

      private void QuestSuccessPlayerDeliveredAnimalsWithoutAcceptingDiscount()
      {
        TraitLevelingHelper.OnIssueSolvedThroughBetrayal(this.QuestGiver, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Mercy, -20)
        });
        ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, 5);
        this.QuestGiver.CurrentSettlement.Village.Hearth += 50f;
        this.ApplyRewards(false);
        this.CompleteQuestWithSuccess();
      }

      private void ApplyRewards(bool applyDiscount)
      {
        if (this._isQuestWithMeatOffer)
        {
          MobileParty.MainParty.ItemRoster.AddToCounts(Game.Current.ObjectManager.GetObject<ItemObject>("meat"), this._offeredMeatAmount);
          foreach (Hero notable in (List<Hero>) this.QuestGiver.CurrentSettlement.Notables)
          {
            if (notable != this.QuestGiver)
              ChangeRelationAction.ApplyPlayerRelation(notable, 3);
          }
        }
        else
          GiveGoldAction.ApplyBetweenCharacters((Hero) null, Hero.MainHero, applyDiscount ? this.RewardGold - this._discountValue : this.RewardGold);
      }

      protected override void OnCompleteWithSuccess()
      {
        this.AddLog(this.QuestSuccessLogText);
        MobileParty.MainParty.ItemRoster.FindIndexOfItem(this._requestedAnimal);
        int num1 = 0;
        for (int index = MobileParty.MainParty.ItemRoster.Count - 1; index >= 0; --index)
        {
          ItemRosterElement itemRosterElement = MobileParty.MainParty.ItemRoster[index];
          EquipmentElement equipmentElement = itemRosterElement.EquipmentElement;
          if (equipmentElement.Item == this._requestedAnimal)
          {
            int num2 = itemRosterElement.Amount >= this._requestedAnimalAmount ? this._requestedAnimalAmount - num1 : itemRosterElement.Amount;
            EquipmentElement rosterElement;
            ref EquipmentElement local = ref rosterElement;
            equipmentElement = itemRosterElement.EquipmentElement;
            ItemObject itemObject = equipmentElement.Item;
            equipmentElement = itemRosterElement.EquipmentElement;
            ItemModifier itemModifier = equipmentElement.ItemModifier;
            local = new EquipmentElement(itemObject, itemModifier);
            MobileParty.MainParty.ItemRoster.AddToCounts(rosterElement, -num2);
            num1 += itemRosterElement.Amount;
            if (num1 >= this._requestedAnimalAmount)
              break;
          }
        }
        TraitLevelingHelper.OnIssueSolvedThroughBetrayal(this.QuestGiver, new Tuple<TraitObject, int>[1]
        {
          new Tuple<TraitObject, int>(DefaultTraits.Honor, 30)
        });
        this.QuestGiver.AddPower(10f);
      }

      protected override void OnTimedOut()
      {
        this.AddLog(this.QuestFailedWithTimeOutLogText);
        this.QuestGiver.AddPower(-10f);
        ChangeRelationAction.ApplyPlayerRelation(this.QuestGiver, -5);
        this.QuestGiver.CurrentSettlement.Village.Hearth -= 30f;
      }

      protected override void HourlyTick()
      {
      }

      protected override void RegisterEvents()
      {
        CampaignEvents.WarDeclared.AddNonSerializedListener((object) this, new Action<IFaction, IFaction, DeclareWarAction.DeclareWarDetail>(this.OnWarDeclared));
        CampaignEvents.OnClanChangedKingdomEvent.AddNonSerializedListener((object) this, new Action<Clan, Kingdom, Kingdom, ChangeKingdomAction.ChangeKingdomActionDetail, bool>(this.OnClanChangedKingdom));
        CampaignEvents.VillageBeingRaided.AddNonSerializedListener((object) this, new Action<Village>(this.OnVillageRaided));
        CampaignEvents.PlayerInventoryExchangeEvent.AddNonSerializedListener((object) this, new Action<List<(ItemRosterElement, int)>, List<(ItemRosterElement, int)>, bool>(this.OnPlayerInventoryExchange));
        CampaignEvents.MapEventStarted.AddNonSerializedListener((object) this, new Action<MapEvent, PartyBase, PartyBase>(this.OnMapEventStarted));
      }

      private void OnMapEventStarted(
        MapEvent mapEvent,
        PartyBase attackerParty,
        PartyBase defenderParty)
      {
        if (!QuestHelper.CheckMinorMajorCoercion((QuestBase) this, mapEvent, attackerParty))
          return;
        QuestHelper.ApplyGenericMinorMajorCoercionConsequences((QuestBase) this, mapEvent);
      }

      private void OnPlayerInventoryExchange(
        List<(ItemRosterElement, int)> purchasedItems,
        List<(ItemRosterElement, int)> soldItems,
        bool isTrading)
      {
        int num1 = 0;
        foreach ((ItemRosterElement, int) purchasedItem in purchasedItems)
        {
          ItemRosterElement itemRosterElement = purchasedItem.Item1;
          if (itemRosterElement.EquipmentElement.Item == this._requestedAnimal)
          {
            int num2 = num1;
            itemRosterElement = purchasedItem.Item1;
            int amount = itemRosterElement.Amount;
            num1 = num2 + amount;
          }
        }
        foreach ((ItemRosterElement, int) soldItem in soldItems)
        {
          ItemRosterElement itemRosterElement = soldItem.Item1;
          if (itemRosterElement.EquipmentElement.Item == this._requestedAnimal)
          {
            int num3 = num1;
            itemRosterElement = soldItem.Item1;
            int amount = itemRosterElement.Amount;
            num1 = num3 - amount;
          }
        }
        this._currentAnimalAmount += num1;
        this._currentAnimalAmount = (int) MathF.Clamp((float) this._currentAnimalAmount, 0.0f, (float) this._requestedAnimalAmount);
        this._questProgressLogTest.UpdateCurrentProgress(this._currentAnimalAmount);
      }

      private void OnVillageRaided(Village village)
      {
        if (village != this.QuestGiver.CurrentSettlement.Village)
          return;
        this.AddLog(this.QuestGiverVillageRaided);
        this.CompleteQuestWithCancel();
      }

      private void OnClanChangedKingdom(
        Clan clan,
        Kingdom oldKingdom,
        Kingdom newKingdom,
        ChangeKingdomAction.ChangeKingdomActionDetail detail,
        bool showNotification = true)
      {
        if (!this.QuestGiver.CurrentSettlement.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction))
          return;
        this.CompleteQuestWithCancel(this.QuestCanceledWarDeclaredLog);
      }

      private void OnWarDeclared(
        IFaction faction1,
        IFaction faction2,
        DeclareWarAction.DeclareWarDetail detail)
      {
        QuestHelper.CheckWarDeclarationAndFailOrCancelTheQuest((QuestBase) this, faction1, faction2, detail, this.PlayerDeclaredWarQuestLogText, this.QuestCanceledWarDeclaredLog);
      }

      protected override void OnFinalize()
      {
      }

      protected override void InitializeQuestOnGameLoad()
      {
        this.CalculateRequestedAnimalCountOnPlayer();
        this.SetDialogs();
      }
    }

    public class HeadmanVillageNeedsDraughtAnimalsIssueBehaviorTypeDefiner : SaveableTypeDefiner
    {
      public HeadmanVillageNeedsDraughtAnimalsIssueBehaviorTypeDefiner()
        : base(812000)
      {
      }

      protected override void DefineClassTypes()
      {
        this.AddClassDefinition(typeof (HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssue), 1);
        this.AddClassDefinition(typeof (HeadmanVillageNeedsDraughtAnimalsIssueBehavior.HeadmanVillageNeedsDraughtAnimalsIssueQuest), 2);
      }
    }
  }
}
